

import java.util.Calendar;
import java.util.Date;

public class TicketTime {

	private static final int TAGES_ANFANG = 8;
	private static final int TAGES_ENDE = 17;

	private final Calendar startzeit;
	private Calendar now;
	private final float hours_left;
	private long time;
	private int stunden_pro_tag;

	public TicketTime(Date startzeit, Date now, float hours_left) {
		stunden_pro_tag = TAGES_ENDE - TAGES_ANFANG;
		this.startzeit = Calendar.getInstance();
		this.startzeit.setTime(startzeit);
		this.now = Calendar.getInstance();
		this.now.setTime(now);
		this.hours_left = hours_left;
		getTimeLeft();
	}

	private void getTimeLeft() {
		Calendar endzeit = Calendar.getInstance();
		endzeit.setTime(getEndZeit());
		while (isTimeOutOfWorkingTime(now)) {
			now.set(Calendar.MINUTE, 0);
			now.set(Calendar.SECOND, 0);
			now.add(Calendar.HOUR_OF_DAY, 1);
		}
		time =  countTime(now, endzeit);
	}

	public boolean isTimeOutOfWorkingTime(Calendar time) {
		return time.get(Calendar.HOUR_OF_DAY) >= TAGES_ENDE || time.get(Calendar.HOUR_OF_DAY) < TAGES_ANFANG || FreeDays.isFreeDay(time);
	}

	public int getDays() {
		return (int) time / (1000 * 60 * 60 * stunden_pro_tag);
	}

	public int getHours() {
		return (int) (time / (1000 * 60 * 60) % stunden_pro_tag);
	}

	public int getMinutes() {
		return (int) time / (1000 * 60) % 60;
	}

	public int getSeconds() {
		return (int) time / (1000) % 60;
	}

	public long getTime() {
		return time;
	}

	public void addSeconds(int seconds) {
		this.time += seconds * 1000;
	}

	public String getCurrentTimeLeft() {
		long time = this.time;
		boolean minusflag = false;
		if (time < 0) {
			time = time * -1;
			minusflag = true;
		}

		stunden_pro_tag = TAGES_ENDE - TAGES_ANFANG;
		long seconds = (long) time / (1000) % 60;
		long minutes = (long) time / (1000 * 60) % 60;
		long stunden = (long) time / (1000 * 60 * 60) % stunden_pro_tag;
		long tage = (long) time / (1000 * 60 * 60 * stunden_pro_tag);
		String vorzeichen = "";
		if (minusflag) {
			vorzeichen = "-";
			time = time * -1;
		}

		return String.format(vorzeichen + "%1dT %02d:%02d:%02d", tage, stunden, minutes, seconds);
	}

	public long countTime(Calendar start, Calendar end) {
		int multiplicator = 1;
		if (start.compareTo(end) > 0) {
			Calendar helper = start;
			start = end;
			end = helper;
			multiplicator = -1;
		}

		int hours = 0;
		int minutes = 0;
		int seconds = 0;
		while ((start.getTimeInMillis() % 1000) != (end.getTimeInMillis() % 1000 )) {
			start.add(Calendar.MILLISECOND, 1);
		}
		while ((start.getTimeInMillis() / 1000 % 60) != (end.getTimeInMillis() / 1000 % 60)) {
			seconds++;
			start.add(Calendar.SECOND, 1);
		}
		while ((start.getTimeInMillis() / (1000 * 60) % 60) != (end.getTimeInMillis() / (1000 * 60) % 60)) {
			minutes++;
			start.add(Calendar.MINUTE, 1);
		}

		while (start.getTimeInMillis() != end.getTimeInMillis()) {
//			int startHour = start.get(Calendar.HOUR_OF_DAY);
			if (isTimeOutOfWorkingTime(start)) {
				start.add(Calendar.HOUR_OF_DAY, 1);
			} else {
				start.add(Calendar.HOUR_OF_DAY, 1);
				hours++;
			}
		}
		long helper = hours * 60 * 60 + minutes * 60 + seconds;
		return helper * 1000 * multiplicator;
	}

	public Date getEndZeit() {
		Calendar endzeit = Calendar.getInstance();
		endzeit.setTime(startzeit.getTime());
		if (isTimeOutOfWorkingTime(endzeit)) {
			endzeit.set(Calendar.MINUTE, 0);
			endzeit.set(Calendar.SECOND, 0);
			endzeit.add(Calendar.HOUR_OF_DAY, 1);
		}
		for (int i = 0; i < hours_left; i++) {
			do {
				endzeit.add(Calendar.HOUR, 1);
			} while (isTimeOutOfWork(endzeit));
		}
		while(isTimeOutOfWorkingTime(endzeit)) {
			endzeit.add(Calendar.HOUR, 1);
		}
		return endzeit.getTime();

	}

	public boolean isTimeOutOfWork(Calendar zeit) {
		return zeit.get(Calendar.HOUR_OF_DAY) > TAGES_ENDE || zeit.get(Calendar.HOUR_OF_DAY) <= TAGES_ANFANG || FreeDays.isFreeDay(zeit);
	}


}
